]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/Bonjour Safari Extension/SafariExtensionHandler.m
mDNSResponder-1096.0.2.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / Bonjour Safari Extension / SafariExtensionHandler.m
1 /*
2 *
3 * Copyright (c) 2017 Apple Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #import "SafariExtensionHandler.h"
19 #import "SafariExtensionViewController.h"
20
21 //#define SHOW_BROWSE_COUNT 1
22
23 #if SHOW_BROWSE_COUNT
24 #include <dns_sd.h>
25
26 static void browseReply( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context );
27 #endif
28
29 @interface SafariExtensionHandler ()
30
31 @property (strong) NSMutableDictionary * instanceD;
32 #if SHOW_BROWSE_COUNT
33 @property (strong) dispatch_queue_t instanceBrowseQ;
34 @property (assign) DNSServiceRef instanceRef; // Never released!!!
35 #endif
36
37 @end
38
39 @implementation SafariExtensionHandler
40
41 - (instancetype)init
42 {
43 if( self = [super init] )
44 {
45 #if SHOW_BROWSE_COUNT
46 self.instanceD = [NSMutableDictionary dictionary];
47 [self startInstanceBrowse];
48 #endif
49 }
50 return( self );
51 }
52
53 - (void)validateToolbarItemInWindow:(SFSafariWindow *)window validationHandler:(void (^)(BOOL enabled, NSString *badgeText))validationHandler {
54 // This method will be called whenever some state changes in the passed in window. You should use this as a chance to enable or disable your toolbar item and set badge text.
55 (void)window; // Unused
56 validationHandler(YES, _instanceD.count ? [NSNumber numberWithInteger: _instanceD.count].stringValue : @"");
57 }
58
59 - (SFSafariExtensionViewController *)popoverViewController {
60 return [SafariExtensionViewController sharedController];
61 }
62
63 #if SHOW_BROWSE_COUNT
64 - (void)startInstanceBrowse
65 {
66 if( !_instanceBrowseQ )
67 {
68 self.instanceBrowseQ = dispatch_queue_create( "DNSAllServiceBrowse", DISPATCH_QUEUE_PRIORITY_DEFAULT );
69 dispatch_set_context( _instanceBrowseQ, (void *)CFBridgingRetain( self ) );
70 dispatch_set_finalizer_f( _instanceBrowseQ, finalizer );
71 }
72
73 dispatch_sync( _instanceBrowseQ, ^{
74 [_instanceD removeAllObjects];
75 });
76
77 DNSServiceErrorType error;
78 if( (error = DNSServiceBrowse( &_instanceRef, 0/*no flags*/, 0, @"_http._tcp".UTF8String, "", browseReply, (__bridge void *)self )) != 0 )
79 NSLog(@"DNSServiceBrowse failed error: %ld", error);
80
81 if( !error )
82 {
83 error = DNSServiceSetDispatchQueue( _instanceRef, _instanceBrowseQ );
84 if( error ) NSLog( @"DNSServiceSetDispatchQueue error: %d", error );
85 }
86 }
87
88 #pragma mark - Dispatch
89
90 static void finalizer( void * context )
91 {
92 SafariExtensionHandler *self = (__bridge SafariExtensionHandler *)context;
93 NSLog( @"finalizer: %@", self );
94 (void)CFBridgingRelease( (__bridge void *)self );
95 }
96
97 #pragma mark - DNS callbacks
98
99 static void browseReply( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context )
100 {
101 (void)sdRef; // Unused
102 (void)interfaceIndex; // Unused
103 (void)errorCode; // Unused
104 SafariExtensionHandler *self = (__bridge SafariExtensionHandler *)context;
105 char fullNameBuffer[kDNSServiceMaxDomainName];
106 if( DNSServiceConstructFullName( fullNameBuffer, serviceName, regtype, replyDomain ) == kDNSServiceErr_NoError )
107 {
108 NSString *fullName = @(fullNameBuffer);
109
110 if( flags & kDNSServiceFlagsAdd )
111 {
112 [self.instanceD setObject: fullName
113 forKey: fullName];
114 }
115 else
116 {
117 [self.instanceD removeObjectForKey: fullName];
118 }
119 }
120 }
121 #endif
122
123 @end